package cn.myframe.utils;

import lombok.extern.slf4j.Slf4j;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.UUID;

@Slf4j
public class CryptPwdUtil {

	/**
	 * MD5加密方法，根据输入字符串，进行md5加密后，输出加密后的字符串
	 * @param src：要加密的原始字符串
	 * @return：输入字符串有效（不为null），则返回MD5加密后的字符串；否则返回null
	 */
	public static String md5(String src){
		if(src == null){
			return null;
		}
		MessageDigest md5 = null;
		try {
			md5 = MessageDigest.getInstance("MD5");
		} catch (NoSuchAlgorithmException e) {
			log.error("Ocurred exception when MD5 encrypt string:", e);
			e.printStackTrace();
			return null;
		}
		byte[] inStrArray = src.getBytes(StandardCharsets.UTF_8);
		byte[] md5Bytes = md5.digest(inStrArray);
		StringBuffer hexValue = new StringBuffer();
		int val;
		for (int i = 0; i < md5Bytes.length; i++) {
			val = ((int) md5Bytes[i]) & 0xff;
			if(val < 16){
				hexValue.append("0");
			}
			hexValue.append(Integer.toHexString(val));
		}
		return hexValue.toString();
	}
	
	/**
	 * SHA-256加密方法，根据输入字符串，进行SHA-256方式加密，返回加密后的字符串
	 * @param src：要加密的原始字符串
	 * @return 输入字符串有效（不为null），则返回SHA-256加密后的字符串；否则返回null
	 */
	public static String sha256(String src){
		if(src == null){
			return null;
		}
		MessageDigest sha256 = null;
		try {
			sha256 = MessageDigest.getInstance("SHA-256");
		} catch (NoSuchAlgorithmException e) {
			log.error("Ocurred exception when SHA-256 encrypt string:", e);
			e.printStackTrace();
			return null;
		}
		byte[] inStrArray = src.getBytes(StandardCharsets.UTF_8);
		byte[] sha256Bytes = sha256.digest(inStrArray);
		StringBuffer hexValue = new StringBuffer();
		int val;
		for (int i = 0; i < sha256Bytes.length; i++) {
			val = ((int) sha256Bytes[i]) & 0xff;
			if(val < 16){
				hexValue.append("0");
			}
			hexValue.append(Integer.toHexString(val));
		}
		return hexValue.toString();
	}
	
	/**
	 * HmacSHA256加密方法
	 * @param key：加密共享密匙
	 * @param src：要加密的字符串
	 * @return：成功返回加密后的字符串，否则返回null
	 */
	public static String hmacSha256(String key,String src){
		if(key == null || src == null){
			return null;
		}
		SecretKeySpec signKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
		Mac mac;
		try {
			mac = Mac.getInstance("HmacSHA256");
			mac.init(signKey);
			byte[] hmacSha256Bytes = mac.doFinal(src.getBytes(StandardCharsets.UTF_8));
			StringBuffer hexValue = new StringBuffer();
			int val;
			for (int i = 0; i < hmacSha256Bytes.length; i++) {
				val = ((int) hmacSha256Bytes[i]) & 0xff;
				if(val < 16){
					hexValue.append("0");
				}
				hexValue.append(Integer.toHexString(val));
			}
			return hexValue.toString();
		} catch (Exception e) {
			log.error("Ocurred exception when hmacSha256 encrypt String:", e);
			e.printStackTrace();
		} 
		return null;
	}
	
	public static String randomStr(){
		return UUID.randomUUID().toString().replace("-", "");
	}
	
	public static String utcTimeStr(){
		Calendar cal = Calendar.getInstance();
		int offset = cal.get(Calendar.ZONE_OFFSET);
		int dstOffset = cal.get(Calendar.DST_OFFSET);
		cal.add(Calendar.MILLISECOND, -(offset+dstOffset));
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		return sdf.format(cal.getTime());
	}
	
	public static String appendHmac(String key){
	    StringBuffer sb = new StringBuffer();
	    sb.append(randomStr());
	    sb.append(key);
	    sb.append(utcTimeStr());
	    return sb.toString();
	}
	
	
	/*public static void main(String[] args) {
		String sha256Str = null;
		sha256Str = CryptPwdUtil.hmacSha256("40895801b30c40d58615cfe1d2f672d2admin","Rojao@123");
		System.out.println("sha256Str : "+sha256Str);
	}*/
}
